﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MediaStockRepositoryTests.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the MediaStockRepositoryTests type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace EFRepositoryTests
{
  using System;
  using System.Collections.Generic;
  using System.Configuration;
  using System.Data.Entity;
  using System.Linq;
  using System.Transactions;
  using BuildMeA;
  using DocProcessingRepository.Repositories;
  using Entities;
  using FluentAssertions;
  using NUnit.Framework;

  [Category("Integration")]
  [TestFixture]
  public class MediaStockRepositoryTests
  {
    private TransactionScope transactionScope;

    private MediaStockRepository mediaStockRepository;
    private StockRepository stockRepository;
    private MediaDefinitionRepository mediaDefinitionRepository;
    private ApplicationUserRepository applicationUserRepository;

    private ApplicationUser user;
    private MediaDefinition mediaDefinition;
    private Stock stock;

    private MediaStock mediaStock;

    [SetUp]
    public void Setup()
    {
      this.transactionScope = new TransactionScope();

      String connectionString = ConfigurationManager.ConnectionStrings["BBOS"].ConnectionString;

      this.mediaStockRepository = new MediaStockRepository(connectionString);
      this.stockRepository = new StockRepository(connectionString);
      this.mediaDefinitionRepository = new MediaDefinitionRepository(connectionString);
      this.applicationUserRepository = new ApplicationUserRepository(connectionString);

      this.user = BuildMeA.ApplicationUser("user1");

      this.mediaDefinition = BuildMeA.MediaDefinition(1, 1, 1, 1, this.user.Id, "test", false, false);

      this.stock = BuildMeA.Stock(1, "Code", "Description", 0, 0, 0, "0", new DateTime(2015, 1, 1));

      this.stockRepository.Create(this.stock);
      this.applicationUserRepository.Create(this.user);
      this.mediaDefinitionRepository.Create(this.mediaDefinition);
      
      this.mediaStock = BuildMeA.MediaStock(1, 1, this.mediaDefinition.MediaDefID, new DateTime(2015, 1, 1), 1);

      this.mediaStockRepository.Create(this.mediaStock);
    }

    [TearDown]
    public void TearDown()
    {
      this.transactionScope.Dispose();
    }

    [Test]
    public void GivenAMediaDefinitionId_WhenIAskForAMediaStock_IGetAMediaStock()
    {
      MediaStockEntity result = this.mediaStockRepository.GetById(this.mediaStock.MediaStockID);

      result.MediaStockId.Should().Be(this.mediaStock.MediaStockID);
    }

    [Test]
    public void GivenAMediaDefinitionId_WhenIAskForTheMediaStock_IGetTheMediaStock()
    {
      List<MediaStockEntity> result = this.mediaStockRepository.GetByMediaDefinition(this.mediaDefinition.MediaDefID);

      result.Count.Should().BeGreaterThan(0);
    }

    [Test]
    public void GivenValidData_WhenIUpdateTheStationNumber_TheStationNumberInTheDBIsUpdated()
    {
      MediaStock existingMediaStock = this.mediaStockRepository.Entities.Single(ms => ms.MediaStockID == this.mediaStock.MediaStockID);

      existingMediaStock.StationNumber.Should().Be(1);

      this.mediaStockRepository.UpdateStationNumber(this.mediaStock.MediaStockID, 5);

      MediaStock updatedMediaStock = this.mediaStockRepository.Entities.AsNoTracking().Single(ms => ms.MediaStockID == this.mediaStock.MediaStockID);

      updatedMediaStock.StationNumber.Should().Be(5);
    }

    [Test]
    public void GivenValidData_WhenIDeleteTheMediaStock_TheMediaStockIsDeletedFromTheDB()
    {
      Int32 originalCount =
        this.mediaStockRepository.Entities.Count(ms => ms.MediaStockID == this.mediaStock.MediaStockID);

      originalCount.Should().Be(1);

      this.mediaStockRepository.DeleteMediaStock(this.mediaStock.MediaStockID);

      Int32 newCount = this.mediaStockRepository.Entities.Count(ms => ms.MediaStockID == this.mediaStock.MediaStockID);

      newCount.Should().Be(0);
    }

    [Test]
    public void GivenValidData_WhenIAddMediaStock_TheMediaStockIsAddedToTheDB()
    {
      MediaStock missingMediaStock = this.mediaStockRepository.Entities.SingleOrDefault(
        ms => ms.StockID == this.stock.StockID && ms.MediaDefID == this.mediaDefinition.MediaDefID);

      missingMediaStock.Should().BeNull();

      this.mediaStockRepository.AddMediaStock(this.stock.StockID, this.mediaDefinition.MediaDefID, 10);

      MediaStock addedMediaStock = this.mediaStockRepository.Entities.SingleOrDefault(
        ms => ms.StockID == this.stock.StockID && ms.MediaDefID == this.mediaDefinition.MediaDefID);

      addedMediaStock.Should().NotBeNull();
      addedMediaStock.StationNumber.Should().Be(10);
    }
  }
}